﻿using Entity;
using IRepository;
using IService;
using System.Data.Common;

namespace Service
{
    public class TransferOrderService : ITransferOrderService
    {
        private readonly ITransferOrderRepository _transferOrderRepository;
        private readonly IStorageLocationRepository _storageLocationRepository;

        public TransferOrderService(ITransferOrderRepository transferOrderRepository, IStorageLocationRepository storageLocationRepository)
        {
            _transferOrderRepository = transferOrderRepository;
            _storageLocationRepository = storageLocationRepository;
        }

        public async Task<bool> CancelAsync(int transferOrderId, string operatorUser)
        {
            if (transferOrderId <= 0)
                throw new ArgumentException("调拨单ID必须为正数");
            if (string.IsNullOrEmpty(operatorUser))
                throw new ArgumentException("操作人不能为空");

            var transferOrder = await _transferOrderRepository.GetByIdAsync(transferOrderId);
            if (transferOrder == null)
                throw new KeyNotFoundException($"调拨单ID {transferOrderId} 不存在");

            if (!IsCancelable(transferOrder.DocumentStatus))
            {
                throw new InvalidOperationException($"当前状态[{transferOrder.DocumentStatus}]不允许撤销");
            }

            return await _transferOrderRepository.CancelAsync(transferOrderId, operatorUser);
        }

        private bool IsCancelable(string documentStatus)
        {
            return new[] { "3", "4" }.Contains(documentStatus);
        }

        // 传递所有必要参数（ioType、ioStatus、pageSize、endDate 等）
        public async Task<List<TransferOrderDTO>> GetTransferOrdersAsync(
            string transnoNo,
            string documentStatus,
            string ioType,
            string ioStatus,
            DateTime? startDate,
            DateTime? endDate,
            int pageIndex,
            int pageSize)
        {
            return await _transferOrderRepository.GetTransferOrdersAsync(
                transnoNo, documentStatus, ioType, ioStatus, startDate, endDate, pageIndex, pageSize);
        }

        public async Task<int> GetTransferOrdersCountAsync(
            string transnoNo,
            string documentStatus,
            string ioType,
            string ioStatus,
            DateTime? startDate,
            DateTime? endDate)
        {
            return await _transferOrderRepository.GetTransferOrdersCountAsync(
                transnoNo, documentStatus, ioType, ioStatus, startDate, endDate);
        }

        public async Task<bool> DeleteAsync(int transferOrderId)
        {
            return await _transferOrderRepository.DeleteAsync(transferOrderId);
        }

        public async Task<bool> BatchDeleteAsync(List<int> ids)
        {
            return await _transferOrderRepository.BatchDeleteAsync(ids);
        }

        public async Task<TransferOrderDTO> GetTransferOrderByIdAsync(int id)
        {
            if (id <= 0)
                throw new ArgumentException("调拨单ID必须大于0", nameof(id));

            return await _transferOrderRepository.GetByIdAsync(id);
        }

        public async Task<bool> CreateTransferAsync(TransferOrderCreateDTO dto)
        {
            if (dto == null)
                throw new ArgumentNullException(nameof(dto), "调拨单数据不能为空");

            return await _transferOrderRepository.AddAsync(dto);
        }

        public async Task<List<TransferOrderDetailDTO>> GetTransferOrderDetailsAsync(int transferOrderId)
        {
            return await _transferOrderRepository.GetDetailsByOrderIdAsync(transferOrderId);
        }

        public async Task<bool> AuditAsync(int transferOrderId, string auditor)
        {
            return await _transferOrderRepository.AuditAsync(transferOrderId, auditor);
        }

        public async Task<List<StorageLocationEntity>> GetStorageLocationsByWarehouseAsync(int warehouseId)
        {
            return await _storageLocationRepository.GetByWarehouseIdAsync(warehouseId);
        }

        public async Task<bool> AuditAsync(int transferOrderId, string auditor, string auditResult)
        {
            return await _transferOrderRepository.AuditAsync(transferOrderId, auditor, auditResult);
        }

        public async Task<List<TransferOrderExportDTO>> GetExportDataAsync(string transnoNo, string documentStatus, string ioStatus, DateTime? startDate, DateTime? endDate)
        {
            return await _transferOrderRepository.GetExportDataAsync(transnoNo, documentStatus, ioStatus, startDate, endDate);
        }

        public async Task<bool> UpdateStatusAsync(int id, string documentStatus, string outboundStatus, string storageStatus)
        {
            var transferOrder = await _transferOrderRepository.GetByIdAsync(id);
            if (transferOrder == null) return false;

            transferOrder.DocumentStatus = documentStatus;
            transferOrder.OutboundStatus = outboundStatus;
            transferOrder.StorageStatus = storageStatus;
            transferOrder.ReviewTime = DateTime.Now;

            await _transferOrderRepository.UpdateAsync(transferOrder);
            return true;
        }

        public async Task<bool> AuditAsync(int transferOrderId, string auditor, string auditResult, DbTransaction transaction)
        {
            return await _transferOrderRepository.AuditAsync(transferOrderId, auditor, auditResult, transaction);
        }

        public async Task<bool> UpdateStatusAsync(int id, string documentStatus, string outboundStatus, string storageStatus, DbTransaction transaction)
        {
            var transferOrder = await _transferOrderRepository.GetByIdAsync(id, transaction);
            if (transferOrder == null) return false;

            transferOrder.DocumentStatus = documentStatus;
            transferOrder.OutboundStatus = outboundStatus;
            transferOrder.StorageStatus = storageStatus;
            transferOrder.ReviewTime = DateTime.Now;

            await _transferOrderRepository.UpdateAsync(transferOrder, transaction);
            return true;
        }

        public async Task<TransferOrderDTO> GetTransferOrderByIdAsync(int id, DbTransaction transaction)
        {
            if (id <= 0)
                throw new ArgumentException("调拨单ID必须大于0", nameof(id));

            return await _transferOrderRepository.GetByIdAsync(id, transaction);
        }

        public async Task<List<TransferOrderDetailDTO>> GetTransferOrderDetailsAsync(int transferOrderId, DbTransaction transaction)
        {
            if (transferOrderId <= 0)
                throw new ArgumentException("调拨单ID必须大于0", nameof(transferOrderId));

            return await _transferOrderRepository.GetDetailsByOrderIdAsync(transferOrderId, transaction);
        }
    }
}